home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / HyperSimple / HyperSimple.c next >
Text File  |  1990-12-22  |  17KB  |  727 lines

  1. /****************************************************************
  2.  *
  3.  *    HyperSimple.c
  4.  *
  5.  *    Simple XCmd for Hypercard 2.0 that demonstrates the use
  6.  *    of the external windows extensions.  This will compile
  7.  *    with MPW or THINK (at least 4.0.4).
  8.  *
  9.  *    These calls are actually fairly easy to use.  There are,
  10.  *    naturally, some holes in the documentation.  For instance,
  11.  *    while you as the XCMD writer *do* own the window's refCon,
  12.  *    you *do not* own the windowKind field, which is used by
  13.  *    Hypercard to keep track of the windows.
  14.  *
  15.  *    Here's the MPW build stuff:
  16.  
  17. HyperSimple ƒƒ HyperSimple.c.o HyperXLib.o
  18.     Link -w -t rsrc -c RSED -rt XCMD=1000 -m MAIN -sg HyperSimple -sym on -mf ∂
  19.         HyperSimple.c.o HyperXLib.o ∂
  20.         "{CLibraries}"StdClib.o ∂
  21.         "{CLibraries}"CInterface.o ∂
  22.         "{CLibraries}"CRuntime.o ∂
  23.         "{Libraries}"Interface.o ∂
  24.         -o HyperSimple
  25.     
  26. HyperSimple.c.o ƒ HyperSimple.c
  27.      C -sym on -b -r HyperSimple.c
  28.  
  29.  *    The THINK C project format is: 
  30.  *
  31.  *        Name:    HyperSimple
  32.  *        Type:    XCMD
  33.  *        ID:        1000
  34.  *        Attrs:    20 (purgeable)
  35.  *
  36.  *        Use <MacHeaders>
  37.  *
  38.  *        Libraries included:
  39.  *            MacTraps
  40.  *            HyperXLib.π
  41.  *            ANSI-A4 (for strlen)
  42.  *
  43.  *    This is sample code, so I hope that you learn from it.
  44.  *    Please note, however, that it is:
  45.  *
  46.  *        Copyright © 1990 Bill Hofmann, All rights reserved
  47.  *
  48.  *    Any comments or questions are welcome, and can be addressed to:
  49.  *
  50.  *        Bill Hofmann
  51.  *        PO Box 460904
  52.  *        San Francisco CA 94146
  53.  *
  54.  *        Internet: wdh@well.sf.ca.us
  55.  *        AppleLink: D6082
  56.  *
  57.  *    Enjoy!
  58.  *
  59.  *    Edit history
  60.  *
  61.  *    10/30/90    wdh        created
  62.  *    12/22/90    wdh        revised and documented
  63.  *
  64.  ****************************************************************/
  65.  
  66. #include    "MPWandTHINK.h"
  67.  
  68. #ifdef    THINK_C
  69. #include    <string.h>
  70. #else    /* MPW */
  71. #include    <Memory.h>
  72. #include    <ToolUtils.h>
  73. #include    <String.h>
  74. #endif    THINK_C
  75. #include    "HyperXCmd.h"
  76.  
  77. #ifndef    NIL
  78. #define    NIL    ((void *) 0)
  79. #endif    NIL
  80.  
  81. /****************************************************************/
  82. /********                Defines                            *********/
  83. /****************************************************************/
  84.  
  85. #define        msgUsage            "HyperSimple <title> [, <bounds rect> ]]"
  86. #define        msgVersion            "HyperSimple v1.0 12/22/90 © Bill Hofmann"
  87. #define        msgBadDiameter        "Error: Diameter must be greater than zero." 
  88. #define        msgBadWindowSize    "Error: New window size must be greater than \"32, 32\"." 
  89. #define        msgParmErr            "Parameter error."
  90.  
  91. #define    supportedProperties    \
  92.             "loc, visible, properties, diameter, size"
  93.  
  94. #define        strDefaultTitle        "\pUntitled"
  95.  
  96. #define        kDefaultDiameter    20
  97.  
  98. /****************************************************************/
  99. /********                typedefs                        *********/
  100. /****************************************************************/
  101.  
  102. typedef struct {
  103.     Point    center;
  104.     long    color;
  105. }    windoid_object;
  106.  
  107. typedef    struct {
  108.     short            diameter;
  109.     short            numObjects;
  110.     windoid_object    obj[100];
  111. }    wobj, ** wobjhdl;
  112.  
  113. /****************************************************************/
  114. /********                Prototypes                        *********/
  115. /****************************************************************/
  116.  
  117. void            CreateWindoid(const XCmdPtr paramPtr);
  118. void            HandleEvent(const XCmdPtr paramPtr, const XWEventInfoPtr event);
  119. void            do_circle(const wobjhdl wobjh, const windoid_object what);
  120. void            do_activate(const XCmdPtr paramPtr, const WindowPtr wp, const short modifiers);
  121. void            do_update(const WindowPtr wp);
  122. void            do_click(const XCmdPtr paramPtr, const EventRecord * evnt, WindowPtr wp);
  123. void            do_key(const XCmdPtr paramPtr, const EventRecord * evnt, const WindowPtr wp);
  124. void            doCloseEvt(const XCmdPtr paramPtr, const XWEventInfoPtr evnt);
  125. OSType            GetFirstFourLwr(const StringPtr what);
  126. void            doSetPropEvt(const XCmdPtr paramPtr, const XWEventInfoPtr evnt);
  127. void            doGetPropEvt(const XCmdPtr paramPtr, const XWEventInfoPtr evnt);
  128. void            doCursorWithin(const XCmdPtr paramPtr, const XWEventInfoPtr evnt);
  129. void            do_content_click(const WindowPtr wp, Point where);
  130. void            do_mfevent(const XCmdPtr paramPtr, const WindowPtr wp, const long message);
  131. void            LocalToGlobalRect(const Rect * rectP);
  132. Handle            strToParam(const char * str);
  133.  
  134. /****************************************************************/
  135. /********                Code                            *********/
  136. /****************************************************************/
  137.  
  138. pascal void
  139. main(const XCmdPtr paramPtr)
  140. {
  141.     XWEventInfoPtr    event;
  142.     
  143.     paramPtr->returnValue = NIL;
  144.     paramPtr->passFlag = false;
  145.  
  146.     /* If paramCount is less than zero, the first params entry is a pointer to a
  147.      *    XWEventInfo record-Hypercard is passing us control to handle an event
  148.      *    for a window we've created.
  149.      */
  150.     if (paramPtr->paramCount < 0)
  151.     {
  152.         event = (XWEventInfoPtr)paramPtr->params[0];
  153.         HandleEvent(paramPtr,event);
  154.     }
  155.     /* Otherwise, the user has invoked the XCMD */
  156.     else if (paramPtr->paramCount >= 1)
  157.     {
  158.         /* Apple now recommends that all XCMDs and XFCNs support the following two 
  159.          *    commands: <name> ! and <name> ?, no matter how many parameters they
  160.          *    normally get.
  161.          */
  162.         if (paramPtr->paramCount == 1)
  163.         {
  164.             if (**(paramPtr->params[0]) == '!')
  165.             {
  166.                 paramPtr->returnValue = strToParam(msgVersion);
  167.                 return;
  168.             }
  169.             else if (**(paramPtr->params[0]) == '?')
  170.             {
  171.                 paramPtr->returnValue = strToParam(msgUsage);
  172.                 return;
  173.             }
  174.         }
  175.         /* This particular XCMD creates a window, with the user optionally specifying
  176.          *    a few arguments.
  177.          */
  178.         CreateWindoid(paramPtr);
  179.     }
  180.     else
  181.         paramPtr->returnValue = strToParam(msgUsage);
  182.     return;
  183. }
  184.  
  185. /*
  186.  *    Handle an event, either a system event or a Hypercard event.
  187.  */
  188.  
  189. void
  190. HandleEvent(const XCmdPtr paramPtr, const XWEventInfoPtr evnt)
  191. {
  192.     WindowPtr        wp;
  193.     GrafPtr            savePort;
  194.  
  195.     wp = evnt->eventWindow;
  196.  
  197.     GetPort(&savePort);
  198.     SetPort(wp);
  199.  
  200.     switch (evnt->event.what)
  201.     {
  202.         /* These are system events */
  203.         case mouseDown:
  204.             do_click(paramPtr, &evnt->event, wp);
  205.             break;
  206.         case keyDown:
  207.         case autoKey:
  208.             do_key(paramPtr, &evnt->event, wp);
  209.             break;
  210.         case updateEvt:
  211.             do_update(wp);
  212.             break;
  213.         case activateEvt:
  214.             do_activate(paramPtr, wp, evnt->event.modifiers);
  215.             break;
  216.         case nullEvent:
  217.             break;
  218.         case app4Evt:
  219.             do_mfevent(paramPtr, wp, evnt->event.message);
  220.             break;
  221.  
  222.         /* These are Hypercard events */
  223.         case xOpenEvt:
  224.             /* Hypercard gives us this event just after it creates a window for us.
  225.              *    We should do initialization stuff here that isn't done when we
  226.              *    create the window
  227.              */
  228.             break;
  229.         case xCloseEvt:
  230.             doCloseEvt(paramPtr, evnt);
  231.             break;
  232.  
  233.         case xHidePalettesEvt:
  234.         case xShowPalettesEvt:
  235.             ShowHide(evnt->eventWindow, (evnt->event.what == xShowPalettesEvt));
  236.             break;
  237.  
  238.             /* A user (or another XCMD) can send a message to one of our windows */
  239.         case xSendEvt:
  240.             break;
  241.  
  242.             /* "get the … of window …" or set the … of window … to …" */
  243.         case xSetPropEvt:
  244.             doSetPropEvt(paramPtr, evnt);
  245.             break;
  246.         case xGetPropEvt:
  247.             doGetPropEvt(paramPtr, evnt);
  248.             break;
  249.  
  250.             /* This is the Hypercard equivalent of a mouse-moved event */
  251.         case xCursorWithin:
  252.             doCursorWithin(paramPtr, evnt);
  253.             break;
  254.  
  255.         /* Not playing a sound, so ignore this */
  256.         case xGiveUpSoundEvt:
  257.             break;
  258.  
  259.         /* We never claim edit, so ignore these */
  260.         case xGiveUpEditEvt:
  261.         case xEditUndo:
  262.         case xEditCut:
  263.         case xEditCopy:
  264.         case xEditPaste:
  265.         case xEditClear:
  266.             break;
  267.  
  268.         /* We have no menus, so ignore these */
  269.         case xMenuEvt:
  270.         case xMBarClickedEvt:
  271.             break;
  272.  
  273.         /* We're not writing a debugger or script editor, so ignore these */
  274.         case xShowWatchInfoEvt:
  275.         case xScriptErrorEvt:
  276.         case xDebugErrorEvt:
  277.         case xDebugStepEvt:
  278.         case xDebugTraceEvt:
  279.         case xDebugFinishedEvt:
  280.             break;
  281.     }
  282.     SetPort(savePort);
  283.     return;
  284. }
  285.  
  286. /*
  287.  *    Create a simple window that will allow the user to draw circles,
  288.  *    with some optional parameters possible
  289.  */
  290. void
  291. CreateWindoid(const XCmdPtr paramPtr)
  292. {
  293.     wobjhdl            wobjh;
  294.     WindowPtr        wp;
  295.     WindowPtr        frontDoc;
  296.     Str255            title;
  297.     Byte            boundsStr[64];
  298.     Rect            bounds;
  299.     short            paramCount;
  300.     short            index = 0;
  301.  
  302.     paramCount = paramPtr->paramCount;
  303.     
  304.     /*    The first argument is the window title */
  305.     if (--paramCount >= 0)
  306.         ZeroToPas(paramPtr, *paramPtr->params[index++], title);
  307.     else
  308.         BlockMove(strDefaultTitle, title, strlen(strDefaultTitle) + 1);
  309.  
  310.     /*    The second default argument is the bounding rectangle of the
  311.      *    window, relative to the front document window, which is
  312.      *    presumably the stack which called us.
  313.      */
  314.     if (--paramCount >= 0)
  315.     {
  316.         ZeroToPas(paramPtr, *paramPtr->params[index++], boundsStr);
  317.         StrToRect(paramPtr, boundsStr, &bounds);
  318.         if (paramPtr->result != xresSucc)
  319.             SetRect(&bounds,20,20,270,270);
  320.     }
  321.     else
  322.         SetRect(&bounds,20,20,270,270);
  323.     frontDoc = FrontDocWindow(paramPtr);
  324.     SetPort(frontDoc);
  325.     LocalToGlobalRect(&bounds);
  326.  
  327.     if (wp = NewXWindow(paramPtr,&bounds,title,true,noGrowDocProc,true,false))
  328.     {
  329.         wobjh = (wobjhdl)NewHandleClear(sizeof(wobj));
  330.         if (wobjh != NIL)
  331.         {
  332.             (*wobjh)->diameter = kDefaultDiameter;
  333.             (*wobjh)->numObjects = 0;
  334.         }
  335.         SetWRefCon(wp,(long)wobjh);
  336.         SelectWindow(wp);
  337.     }
  338. }
  339.  
  340. /*
  341.  *    These are the system event handling routines
  342.  */
  343.  
  344. void
  345. do_click(const XCmdPtr paramPtr, const EventRecord * evnt, WindowPtr wp)
  346. {
  347.     GrafPtr            wMgrPort;
  348.     wobjhdl            wobjh;
  349.     short            part;
  350.  
  351.     switch (part = FindWindow(evnt->where,&wp))
  352.     {
  353.         case inContent:
  354.             wobjh = (wobjhdl) GetWRefCon(wp);
  355.             if (wobjh)
  356.             {
  357.                 /* Register to receive keystrokes whenever the user clicks in
  358.                  *    our window.  We're not doing a whole lot with them,
  359.                  *    but this is the place to register.
  360.                  */
  361.                 BeginXWEdit(paramPtr, wp);
  362.                 if (FrontDocWindow(paramPtr) != wp)
  363.                     SelectWindow(wp);
  364.                 else
  365.                     do_content_click(wp, evnt->where);
  366.             }
  367.             break;
  368.         case inDrag:
  369.             /* We can't get the QD globals easily, look at the Window Manager port.
  370.              *    This is equivalent to screenBits.bounds.
  371.              */
  372.             GetWMgrPort(&wMgrPort);
  373.             DragWindow(wp,evnt->where,&wMgrPort->portRect);
  374.             break;
  375.         case inGoAway:
  376.             if (TrackGoAway(wp,evnt->where))
  377.                 CloseXWindow(paramPtr,wp);
  378.             break;
  379.         default:    /* inGrow, inZoomIn, inZoomOut */
  380.             break;
  381.     }
  382.     return;
  383. }
  384.  
  385. void
  386. do_content_click(const WindowPtr wp, Point where)
  387. {
  388.     wobjhdl            wobjh;
  389.     short            i;
  390.     long            color;
  391.  
  392.     /* The port is already set */
  393.     GlobalToLocal(&where);
  394.     if (wobjh = (wobjhdl)GetWRefCon(wp))
  395.     {
  396.         if ((*wobjh)->numObjects < 100)
  397.         {
  398.             i = (Random() / 8192) + 4;
  399.             switch (i)
  400.             {
  401.                 case 0:
  402.                 case 1:
  403.                     color = redColor;
  404.                     break;
  405.                 case 2:
  406.                     color = greenColor;
  407.                     break;
  408.                 case 3:
  409.                     color = blueColor;
  410.                     break;
  411.                 case 4:
  412.                     color = cyanColor;
  413.                     break;
  414.                 case 5:
  415.                     color = magentaColor;
  416.                     break;
  417.                 case 6:
  418.                     color = yellowColor;
  419.                     break;
  420.                 case 7:
  421.                     color = blackColor;
  422.                     break;
  423.             }
  424.             (*wobjh)->obj[(*wobjh)->numObjects].center = where;
  425.             (*wobjh)->obj[(*wobjh)->numObjects].color = color;
  426.             do_circle(wobjh, (*wobjh)->obj[(*wobjh)->numObjects]);
  427.             (*wobjh)->numObjects++;
  428.         }
  429.     }
  430.     return;
  431. }
  432.  
  433. void
  434. do_key(const XCmdPtr paramPtr, const EventRecord * evnt, WindowPtr wp)
  435. {
  436. #pragma    unused(paramPtr)
  437.     wobjhdl            wobjh = (wobjhdl) GetWRefCon(wp);
  438.     long            color;
  439.     Point            where;
  440.  
  441.     /* This is a fairly lame thing to do, but the begin and end edit stuff
  442.      *    isn't entirely intuitive, so I put it in.
  443.      */
  444.     if (wobjh && ((*wobjh)->numObjects < 100))
  445.     {
  446.         switch (evnt->message & charCodeMask)
  447.         {
  448.             case 'r':
  449.             case 'R':
  450.                 color = redColor;
  451.                 break;
  452.             case 'g':
  453.             case 'G':
  454.                 color = greenColor;
  455.                 break;
  456.             case 'b':
  457.             case 'B':
  458.                 color = blueColor;
  459.                 break;
  460.             case 'c':
  461.             case 'C':
  462.                 color = cyanColor;
  463.                 break;
  464.             case 'm':
  465.             case 'M':
  466.                 color = magentaColor;
  467.                 break;
  468.             case 'y':
  469.             case 'Y':
  470.                 color = yellowColor;
  471.                 break;
  472.             default:
  473.                 SysBeep(1);
  474.                 return;
  475.         }
  476.         /* Pick some random location, normalized between 0..max window size */
  477.         where.h = (Random() / (65536L / wp->portRect.right)) + (wp->portRect.right >> 1);        
  478.         where.v = (Random() / (65536L / wp->portRect.bottom)) + (wp->portRect.bottom >> 1);
  479.         (*wobjh)->obj[(*wobjh)->numObjects].center = where;
  480.         (*wobjh)->obj[(*wobjh)->numObjects].color = color;
  481.         do_circle(wobjh, (*wobjh)->obj[(*wobjh)->numObjects]);
  482.         (*wobjh)->numObjects++;
  483.     }
  484.     return;
  485. }
  486.  
  487. void
  488. do_activate(const XCmdPtr paramPtr, const WindowPtr wp, const short modifiers)
  489. {
  490.     /* Here's where we'd show or hide controls and call DrawGrowIcon */
  491.     if (modifiers & activeFlag)
  492.         BeginXWEdit(paramPtr, wp);
  493.     else
  494.         EndXWEdit(paramPtr, wp);
  495.     return;
  496. }
  497.  
  498. void
  499. do_mfevent(const XCmdPtr paramPtr, const WindowPtr wp, const long message)
  500. {
  501. #pragma    unused(paramPtr)
  502.  
  503.     if (((message&osEvtMessageMask) >> 24) == suspendResumeMessage)
  504.         do_activate(paramPtr, wp, (short)message);
  505.     return;
  506. }
  507.  
  508. void
  509. do_update(const WindowPtr wp)
  510. {
  511.     wobjhdl            wobjh;
  512.     short            i;
  513.  
  514.     /* Port is already set */
  515.     BeginUpdate(wp);
  516.         EraseRect(&wp->portRect);
  517.         if (wobjh = (wobjhdl)GetWRefCon(wp))
  518.         {
  519.             for (i = 0; i < (*wobjh)->numObjects; i++)
  520.                 do_circle(wobjh, (*wobjh)->obj[i]);
  521.         }
  522.     EndUpdate(wp);
  523. }
  524.  
  525. void
  526. do_circle(const wobjhdl wobjh, const windoid_object what)
  527. {
  528.     Rect            bounds;
  529.     Point            where = what.center;
  530.     short            radius = (*wobjh)->diameter / 2;
  531.  
  532.     /* Port is already set */
  533.     ForeColor(what.color);
  534.     SetRect(&bounds,where.h - radius, where.v - radius,
  535.                     where.h + radius, where.v + radius);
  536.     PaintOval(&bounds);
  537.     ForeColor(blackColor);
  538.     return;
  539. }
  540.  
  541. /*
  542.  *    These are the routines to support Hypercard events.
  543.  */
  544.  
  545. void
  546. doCloseEvt(XCmdPtr paramPtr, XWEventInfoPtr evnt)
  547. {
  548.     wobjhdl            wobjh;
  549.     
  550.     EndXWEdit(paramPtr, evnt->eventWindow);
  551.     if (wobjh = (wobjhdl)GetWRefCon(evnt->eventWindow))
  552.         DisposHandle((Handle)wobjh);
  553.     /* If we don't set passFlag to true, Hypercard gets all confused */
  554.     paramPtr->passFlag = true;
  555.     return;
  556. }
  557.  
  558. void
  559. doSetPropEvt(const XCmdPtr paramPtr, const XWEventInfoPtr evnt)
  560. {
  561.     WindowPtr        wp;
  562.     StringPtr        property;
  563.     Str255            value;
  564.     long            propCode;
  565.     long            diameter;
  566.     Point            newSize;
  567.     wobjhdl            wobjh;
  568.     OSErr            err = noErr;
  569.     Boolean            passIt = false;
  570.  
  571.     property = (StringPtr)evnt->eventParams[0];    /* pstring */
  572.     ReturnToPas(paramPtr,*(Handle)evnt->eventParams[1],value);
  573.     wp = evnt->eventWindow;
  574.     wobjh = (wobjhdl)GetWRefCon(wp);
  575.  
  576.     propCode = GetFirstFourLwr(property);
  577.     if (property[0] >= 1 && 
  578.         StringMatch(paramPtr, property, supportedProperties) != NIL)
  579.     {
  580.         switch (propCode)
  581.         {
  582.             case 'diam':
  583.                 diameter = StrToNum(paramPtr, value);
  584.                 if (paramPtr->result != xresSucc || diameter <= 0)
  585.                 {
  586.                     err = 1;
  587.                     paramPtr->returnValue = strToParam(msgBadDiameter);
  588.                     break;
  589.                 }
  590.                 (*wobjh)->diameter = diameter;
  591.                 InvalRect(&wp->portRect);
  592.                 break;
  593.             case 'size':
  594.                 StrToPoint(paramPtr, value, &newSize);
  595.                 if (paramPtr->result != xresSucc ||
  596.                     newSize.h <= 32 || newSize.v <= 32)
  597.                 {
  598.                     err = 1;
  599.                     paramPtr->returnValue = strToParam(msgBadWindowSize);
  600.                     break;
  601.                 }
  602.                 SizeWindow(wp, newSize.h, newSize.v, true);
  603.                 break;
  604.         }
  605.     }
  606.     else    /* Haven't a clue. Pass it on. */
  607.         passIt = true;
  608.  
  609.     /* All done.  Check err.  If != noErr, complain */
  610.     if (err > 0)    /* internal error */
  611.         paramPtr->result = xresFail;
  612.     paramPtr->passFlag = passIt;    /* pass the event */
  613.     return;
  614. }
  615.  
  616. void
  617. doGetPropEvt(const XCmdPtr paramPtr, const XWEventInfoPtr evnt)
  618. {
  619.     WindowPtr        wp;
  620.     StringPtr        property;
  621.     Str255            value;
  622.     long            propCode;
  623.     Point            curSize;
  624.     wobjhdl            wobjh;
  625.     Boolean            passIt = false;
  626.  
  627.     property = (StringPtr)evnt->eventParams[0];
  628.     wp = evnt->eventWindow;
  629.     wobjh = (wobjhdl)GetWRefCon(wp);
  630.  
  631.     /* return the value in the eventResult field */
  632.     propCode = GetFirstFourLwr(property);
  633.     evnt->eventResult = NIL;
  634.  
  635.     propCode = GetFirstFourLwr(property);
  636.     if (property[0] >= 1 && 
  637.         StringMatch(paramPtr, property, supportedProperties) != NIL)
  638.     {
  639.         switch (propCode)
  640.         {
  641.             case 'diam':
  642.                 NumToStr(paramPtr, (*wobjh)->diameter, value);
  643.                 evnt->eventResult = PasToZero(paramPtr, value);
  644.                 break;
  645.             case 'size':
  646.                 curSize.h = wp->portRect.right - wp->portRect.left;
  647.                 curSize.v = wp->portRect.bottom - wp->portRect.top;
  648.                 PointToStr(paramPtr, curSize, value);
  649.                 evnt->eventResult = PasToZero(paramPtr, value);
  650.                 break;
  651.             case 'prop':
  652.                 evnt->eventResult = strToParam(supportedProperties);
  653.                 break;
  654.             default:
  655.                 passIt = true;
  656.                 break;
  657.         }
  658.     }
  659.     else    /* Haven't a clue. Pass it on. */
  660.         passIt = true;
  661.     paramPtr->passFlag = passIt;    /* pass the event */
  662.     return;
  663. }
  664.  
  665. void
  666. doCursorWithin(const XCmdPtr paramPtr, const XWEventInfoPtr evnt)
  667. {
  668.     WindowPtr        wp = evnt->eventWindow;
  669.     Point            where;
  670.     CursHandle        crossHair;
  671.     SignedByte        state;
  672.     
  673.     /* The port is set to our window */
  674.     GetMouse(&where);
  675.     if (PtInRgn(where, wp->visRgn))
  676.     {
  677.         if (crossHair = GetCursor(crossCursor))
  678.         {
  679.             state = HGetState((Handle)crossHair);
  680.             HLock((Handle)crossHair);
  681.             SetCursor(*crossHair);
  682.             HSetState((Handle)crossHair, state);
  683.             return;        /* leave passFlag false */
  684.         }
  685.     }
  686.     paramPtr->passFlag = true;    /* this sets cursor to arrow */
  687.     return;
  688. }
  689.  
  690. /****************************************************************/
  691. /********                Utils                            *********/
  692. /****************************************************************/
  693.  
  694. void
  695. LocalToGlobalRect(const Rect * rectP)
  696. {
  697.     LocalToGlobal(&(((Point *) rectP)[0]));
  698.     LocalToGlobal(&(((Point *) rectP)[1]));
  699.     return;
  700. }
  701.  
  702. Handle
  703. strToParam(const char * str)
  704. {
  705.     Handle    out = NIL;
  706.     long    len;
  707.     
  708.     if ((len = strlen(str)) && (out = NewHandle(len + 1)))
  709.         BlockMove(str, *out, len + 1);
  710.     return(out);
  711. }
  712.  
  713. OSType
  714. GetFirstFourLwr(const StringPtr what)
  715. {
  716.     long            firstfour;
  717.  
  718.     firstfour = '    ';    /* four spaces */
  719.     BlockMove(&what[1],(Ptr)&firstfour,(what[0] < 4) ? what[0] : 4);
  720.     LwrText((Ptr)&firstfour,4);
  721.     return(firstfour);
  722. }
  723.  
  724. /*******
  725.  * end *
  726.  *******/
  727.